package com.sourceQ.system.service.tenant.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.sourceQ.common.core.constant.dict.BmTenantPackageStatus;
import com.sourceQ.common.core.utils.StringUtils;
import com.sourceQ.common.core.utils.bean.BeanUtils;
import com.sourceQ.system.domain.tenant.Tenant;
import com.sourceQ.system.domain.tenant.TenantPackage;
import com.sourceQ.system.dto.tenant.TenantPackagePageReqDTO;
import com.sourceQ.system.vo.tenant.TenantPackageRespVO;
import com.sourceQ.system.dto.tenant.TenantPackageSaveReqDTO;
import com.sourceQ.system.mapper.tenant.TenantPackageMapper;
import com.sourceQ.system.service.tenant.TenantPackageService;
import com.sourceQ.system.service.tenant.TenantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.sourceQ.common.core.constant.ErrorCodeConstants.*;
import static com.sourceQ.common.core.utils.ExceptionUtil.exception;

/**
 * @author: SourceQ
 * @create: 2024-03-26 11:09
 * @Description:
 */
@Service
@Validated
public class TenantPackageServiceImpl extends ServiceImpl<TenantPackageMapper,TenantPackage> implements TenantPackageService {

    @Autowired
    @Lazy // 避免循环依赖的报错
    private TenantService tenantService;

    @Override
    public int createTenantPackage(TenantPackageSaveReqDTO createReqVO) {
        TenantPackage tenantPackage = new TenantPackage();
        BeanUtils.copyProperties(createReqVO, tenantPackage);
        tenantPackage.setDelFlag("0");
        tenantPackage.setRoleIds(StringUtils.join(createReqVO.getRoleIds(),","));
        return baseMapper.insert(tenantPackage);
    }

    @Override
    @Transactional
    public void updateTenantPackage(TenantPackageSaveReqDTO updateReqVO) {
        TenantPackage tenantPackage = validateTenantPackageExists(updateReqVO.getId());
        //update，这时需看租户套餐管理的角色是否有变化，有变化需修改购买改套餐的租户的权限绑定。
        BeanUtils.copyProperties(updateReqVO,tenantPackage);
        //角色关联处理
        Set<Long> oldRoleIds = Arrays.stream(tenantPackage.getRoleIds().split(",")).map(Long::parseLong).collect(Collectors.toSet());
        if (!CollUtil.isEqualList(oldRoleIds,updateReqVO.getRoleIds())){
            List<Tenant> tenants = tenantService.getTenantListByPackageId(tenantPackage.getId());
            if (!CollectionUtils.isEmpty(tenants)){
                tenants.forEach(item->tenantService.updateTenantUserRole(item.getId(), updateReqVO.getRoleIds()));
            }
        }
        tenantPackage.setRoleIds(StringUtils.join(updateReqVO.getRoleIds(),","));
        baseMapper.updateById(tenantPackage);
    }

    @Override
    public void deleteTenantPackage(Long[] ids) {
        for (Long id : ids) {
            validateTenantPackageExists(id);
            //校验套餐是否在使用中
            if (tenantService.getTenantCountByPackageId(id)>0){
                throw exception(TENANT_PACKAGE_USED);
            }
            //删除
            baseMapper.deleteById(id);
        }
    }

    @Override
    public TenantPackageRespVO getTenantPackage(Long id) {
        TenantPackage tenantPackage = validateTenantPackageExists(id);
        TenantPackageRespVO vo = new TenantPackageRespVO();
         BeanUtils.copyProperties(tenantPackage,vo);
         vo.setStatus(String.valueOf(tenantPackage.getStatus())).setRoleIds(Arrays.stream(tenantPackage.getRoleIds().split(",")).map(Long::parseLong).collect(Collectors.toSet()));
        return vo;
    }

    @Override
    public IPage<TenantPackage> getTenantPackagePage(Page page, TenantPackagePageReqDTO pageReqVO) {
        return baseMapper.getPageByParams(page,pageReqVO);
    }

    @Override
    public TenantPackage validTenantPackage(Long id) {
        TenantPackage tenantPackage = validateTenantPackageExists(id);
        if (BmTenantPackageStatus.STOP.equals(tenantPackage.getStatus())){
            throw exception(TENANT_PACKAGE_DISABLE);
        }
        return tenantPackage;
    }

    @Override
    public List<TenantPackage> getTenantPackageListByStatus(String status) {
        return baseMapper.selectListByStatus(status);
    }

    @Override
    public List<TenantPackageRespVO> getTenantPackageVoList(TenantPackagePageReqDTO dto) {

        return baseMapper.getAllByParamsToList(dto);
    }

    @Override
    public void changeTenantPackage(Long id, String status) {
        TenantPackage tenantPackage = validateTenantPackageExists(id);
        //校验套餐是否在使用中
        if (tenantService.getTenantCountByPackageId(id)>0){
            throw exception(TENANT_PACKAGE_USED);
        }
        if (StringUtils.isEmpty(status)||StringUtils.containsAny(Lists.newArrayList("0","1"),status)){
            throw exception(PARAMETER_ERROR,status);
        }
        tenantPackage.setStatus(status);
        baseMapper.updateById(tenantPackage);
    }

    /**
     * 校验数据是否存在
     * @param id
     * @return
     */
    private TenantPackage validateTenantPackageExists(Long id){
        TenantPackage tenantPackage = baseMapper.selectById(id);
        if (tenantPackage==null){
            throw exception(TENANT_PACKAGE_NOT_EXISTS);
        }
        return tenantPackage;
    }
}
